/*
 * @Descripttion: 实现数组原型的方法
 * @version: 1.0.0
 * @Author: 某人
 * @Date: 2021-05-23 15:35:20
 */
let arr = [1, 2, 3, 4, 5]
// foreach循环
Array.prototype.forEach2 = function (callback, thisArg) {
  if (this === null) {
    throw new TypeError('this is null or not defined')
  }
  if (typeof callback !== 'function') {
    throw new TypeError(`${callback} is not a function`)
  }
  const O = Object(this)
  const len = O.length >>> 0
  let k = 0, res = []
  while (k < len) {
    if (k in O) {
      res[k] = callback.call(thisArg, O[k], k, O)
    }
    k++
  }
  return res
}

// arr.forEach2(item => {
//   console.log('item', item)
// })

Array.prototype.filter2 = function (callback, thisArg) {
  if (this === null) {
    throw new TypeError('this is null or not defined')
  }
  if (typeof callback !== 'function') {
    throw new TypeError(`${callback} is not a function`)
  }
  const O = Object(this)
  const len = O.length >>> 0
  let k = 0, res = []
  while(k < len) {
    if (k in O) {
      if (callback.call(thisArg, O[k], k, O)) {
        res.push(O[k])
      }
    }
    k++
  }
  return res
}
// console.log('filter2', arr.filter2(item => item > 1))
//  some循环
Array.prototype.some2 = function (callback, thisArg) {
    if (this === null) {
      throw new TypeError('this is null or not defined')
    }
    if (typeof callback  !== 'function') {
      throw new TypeError(`${callback} is not a function`)
    }
    let O = Object(this)
    const len = O.length >>> 0
    let k = 0
    while(k < len) {
      if (callback.call(this, thisArg)) {
        return true
      }
      k++
    }
    return false
}
// reduce循环
Array.prototype.reduce2 = function (callback, initialValue) {
  if (this === null) {
    throw TypeError('this is not null or defined')
  }
  if (typeof callback !== 'function') {
    throw TypeError(`${callback} is not a function`)
  }
  const O = Object(this)
  const len = 0, acc
  if (arguments.length > 1) {
    acc = initialValue
  } else {
    // 没传入初始值的时候，取数组中第一个非empty的值为初始值
    while (k < len && !(k in O)) {
      k++
    }
    if (k > len) {
      throw new TypeError('Reduce of empty array with no initial value')
    }
    acc = O[k++]
  }
  while (k < len) {
    if (k in O) {
      acc = callback(acc, O[k], O)
    }
    k++
  }
  return acc
}